﻿using System;
using System.Collections.Generic;
using Microsoft.WowAddonStudio.FrameXml.Serialization;

namespace Microsoft.WowAddonStudio.FrameXml.Components.Events
{
    [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public sealed class EventGroupAttribute : Attribute
    {
        private static readonly Dictionary<EventGroup, EventName[]> eventGroups = InitializeEventGroups();

        /// <summary>
        /// Initializes a new instance of the <see cref="EventGroupAttribute"/> class.
        /// </summary>
        /// <param name="eventGroup">The event group.</param>
        /// <param name="defaultEventName">The default event.</param>
        public EventGroupAttribute(EventGroup eventGroup, EventName defaultEventName)
        {
            EventGroup = eventGroup;
            DefaultEventName = defaultEventName;
        }

        /// <summary>
        /// Gets or sets the event group.
        /// </summary>
        /// <value>The event group.</value>
        public EventGroup EventGroup { get; private set; }

        /// <summary>
        /// Gets or sets the default event name of the event goup.
        /// </summary>
        /// <value>The default event.</value>
        public EventName DefaultEventName { get; private set; }

        #region InitializeEventGroups
        /// <summary>
        /// Initializes the event group dictionary.
        /// </summary>
        /// <returns></returns>
        private static Dictionary<EventGroup, EventName[]> InitializeEventGroups()
        {
            return new Dictionary<EventGroup, EventName[]>
                       {
                           {
                               EventGroup.Button, new[]
                                                      {
                                                          EventName.OnChar,
                                                          EventName.OnClick,
                                                          EventName.OnDoubleClick,
                                                          EventName.OnDragStart,
                                                          EventName.OnDragStop,
                                                          EventName.OnEnter,
                                                          EventName.OnEvent,
                                                          EventName.OnHide,
                                                          EventName.OnKeyDown,
                                                          EventName.OnKeyUp,
                                                          EventName.OnLeave,
                                                          EventName.OnLoad,
                                                          EventName.OnMouseDown,
                                                          EventName.OnMouseUp,
                                                          EventName.OnMouseWheel,
                                                          EventName.OnReceiveDrag,
                                                          EventName.OnShow,
                                                          EventName.OnSizeChanged,
                                                          EventName.OnUpdate,
                                                          EventName.PostClick,
                                                          EventName.PreClick
                                                      }
                               },
                           {
                               EventGroup.CheckButton, new[]
                                                           {
                                                               EventName.OnChar,
                                                               EventName.OnClick,
                                                               EventName.OnDoubleClick,
                                                               EventName.OnDragStart,
                                                               EventName.OnDragStop,
                                                               EventName.OnEnter,
                                                               EventName.OnEvent,
                                                               EventName.OnHide,
                                                               EventName.OnKeyDown,
                                                               EventName.OnKeyUp,
                                                               EventName.OnLeave,
                                                               EventName.OnLoad,
                                                               EventName.OnMouseDown,
                                                               EventName.OnMouseUp,
                                                               EventName.OnMouseWheel,
                                                               EventName.OnReceiveDrag,
                                                               EventName.OnShow,
                                                               EventName.OnSizeChanged,
                                                               EventName.OnUpdate
                                                           }
                               },
                           {
                               EventGroup.ColorSelect, new[]
                                                           {
                                                               EventName.OnChar,
                                                               EventName.OnColorSelect,
                                                               EventName.OnDragStart,
                                                               EventName.OnDragStop,
                                                               EventName.OnEnter,
                                                               EventName.OnEvent,
                                                               EventName.OnHide,
                                                               EventName.OnKeyDown,
                                                               EventName.OnKeyUp,
                                                               EventName.OnLeave,
                                                               EventName.OnLoad,
                                                               EventName.OnMouseDown,
                                                               EventName.OnMouseUp,
                                                               EventName.OnMouseWheel,
                                                               EventName.OnReceiveDrag,
                                                               EventName.OnShow,
                                                               EventName.OnSizeChanged,
                                                               EventName.OnUpdate
                                                           }
                               },
                           {
                               EventGroup.DressUpModel, new[]
                                                            {
                                                                EventName.OnAnimFinished,
                                                                EventName.OnChar,
                                                                EventName.OnDragStart,
                                                                EventName.OnDragStop,
                                                                EventName.OnEnter,
                                                                EventName.OnEvent,
                                                                EventName.OnHide,
                                                                EventName.OnKeyDown,
                                                                EventName.OnKeyUp,
                                                                EventName.OnLeave,
                                                                EventName.OnLoad,
                                                                EventName.OnMouseDown,
                                                                EventName.OnMouseUp,
                                                                EventName.OnMouseWheel,
                                                                EventName.OnReceiveDrag,
                                                                EventName.OnShow,
                                                                EventName.OnSizeChanged,
                                                                EventName.OnUpdate,
                                                                EventName.OnUpdateModel
                                                            }
                               },
                           {
                               EventGroup.EditBox, new[]
                                                       {
                                                           EventName.OnChar,
                                                           EventName.OnCursorChanged,
                                                           EventName.OnDragStart,
                                                           EventName.OnDragStop,
                                                           EventName.OnEditFocusGained,
                                                           EventName.OnEditFocusLost,
                                                           EventName.OnEnter,
                                                           EventName.OnEnterPressed,
                                                           EventName.OnEscapePressed,
                                                           EventName.OnEvent,
                                                           EventName.OnHide,
                                                           EventName.OnInputLanguageChanged,
                                                           EventName.OnKeyDown,
                                                           EventName.OnKeyUp,
                                                           EventName.OnLeave,
                                                           EventName.OnLoad,
                                                           EventName.OnMouseDown,
                                                           EventName.OnMouseUp,
                                                           EventName.OnMouseWheel,
                                                           EventName.OnReceiveDrag,
                                                           EventName.OnShow,
                                                           EventName.OnSizeChanged,
                                                           EventName.OnSpacePressed,
                                                           EventName.OnTabPressed,
                                                           EventName.OnTextChanged,
                                                           EventName.OnTextSet,
                                                           EventName.OnUpdate
                                                       }
                               },
                           {
                               EventGroup.Frame, new[]
                                                     {
                                                         EventName.OnChar,
                                                         EventName.OnDragStart,
                                                         EventName.OnDragStop,
                                                         EventName.OnEnter,
                                                         EventName.OnEvent,
                                                         EventName.OnHide,
                                                         EventName.OnKeyDown,
                                                         EventName.OnKeyUp,
                                                         EventName.OnLeave,
                                                         EventName.OnLoad,
                                                         EventName.OnMouseDown,
                                                         EventName.OnMouseUp,
                                                         EventName.OnMouseWheel,
                                                         EventName.OnReceiveDrag,
                                                         EventName.OnShow,
                                                         EventName.OnSizeChanged,
                                                         EventName.OnUpdate
                                                     }
                               },
                           {
                               EventGroup.GameTooltip, new[]
                                                           {
                                                               EventName.OnChar,
                                                               EventName.OnDragStart,
                                                               EventName.OnDragStop,
                                                               EventName.OnEnter,
                                                               EventName.OnEvent,
                                                               EventName.OnHide,
                                                               EventName.OnKeyDown,
                                                               EventName.OnKeyUp,
                                                               EventName.OnLeave,
                                                               EventName.OnLoad,
                                                               EventName.OnMouseDown,
                                                               EventName.OnMouseUp,
                                                               EventName.OnMouseWheel,
                                                               EventName.OnReceiveDrag,
                                                               EventName.OnShow,
                                                               EventName.OnSizeChanged,
                                                               EventName.OnTooltipAddMoney,
                                                               EventName.OnTooltipCleared,
                                                               EventName.OnTooltipSetDefaultAnchor,
                                                               EventName.OnTooltipSetItem,
                                                               EventName.OnTooltipSetSpell,
                                                               EventName.OnTooltipSetUnit,
                                                               EventName.OnUpdate
                                                           }
                               },
                           {
                               EventGroup.LootButton, new[]
                                                          {
                                                              EventName.OnChar,
                                                              EventName.OnClick,
                                                              EventName.OnDoubleClick,
                                                              EventName.OnDragStart,
                                                              EventName.OnDragStop,
                                                              EventName.OnEnter,
                                                              EventName.OnEvent,
                                                              EventName.OnHide,
                                                              EventName.OnKeyDown,
                                                              EventName.OnKeyUp,
                                                              EventName.OnLeave,
                                                              EventName.OnLoad,
                                                              EventName.OnMouseDown,
                                                              EventName.OnMouseUp,
                                                              EventName.OnMouseWheel,
                                                              EventName.OnReceiveDrag,
                                                              EventName.OnShow,
                                                              EventName.OnSizeChanged,
                                                              EventName.OnUpdate
                                                          }
                               },
                           {
                               EventGroup.MessageFrame, new[]
                                                            {
                                                                EventName.OnChar,
                                                                EventName.OnDragStart,
                                                                EventName.OnDragStop,
                                                                EventName.OnEnter,
                                                                EventName.OnEvent,
                                                                EventName.OnHide,
                                                                EventName.OnKeyDown,
                                                                EventName.OnKeyUp,
                                                                EventName.OnLeave,
                                                                EventName.OnLoad,
                                                                EventName.OnMouseDown,
                                                                EventName.OnMouseUp,
                                                                EventName.OnMouseWheel,
                                                                EventName.OnReceiveDrag,
                                                                EventName.OnShow,
                                                                EventName.OnSizeChanged,
                                                                EventName.OnUpdate
                                                            }
                               },
                           {
                               EventGroup.Minimap, new[]
                                                       {
                                                           EventName.OnChar,
                                                           EventName.OnDragStart,
                                                           EventName.OnDragStop,
                                                           EventName.OnEnter,
                                                           EventName.OnEvent,
                                                           EventName.OnHide,
                                                           EventName.OnKeyDown,
                                                           EventName.OnKeyUp,
                                                           EventName.OnLeave,
                                                           EventName.OnLoad,
                                                           EventName.OnMouseDown,
                                                           EventName.OnMouseUp,
                                                           EventName.OnMouseWheel,
                                                           EventName.OnReceiveDrag,
                                                           EventName.OnShow,
                                                           EventName.OnSizeChanged,
                                                           EventName.OnUpdate
                                                       }
                               },
                           {
                               EventGroup.Model, new[]
                                                     {
                                                         EventName.OnAnimFinished,
                                                         EventName.OnChar,
                                                         EventName.OnDragStart,
                                                         EventName.OnDragStop,
                                                         EventName.OnEnter,
                                                         EventName.OnEvent,
                                                         EventName.OnHide,
                                                         EventName.OnKeyDown,
                                                         EventName.OnKeyUp,
                                                         EventName.OnLeave,
                                                         EventName.OnLoad,
                                                         EventName.OnMouseDown,
                                                         EventName.OnMouseUp,
                                                         EventName.OnMouseWheel,
                                                         EventName.OnReceiveDrag,
                                                         EventName.OnShow,
                                                         EventName.OnSizeChanged,
                                                         EventName.OnUpdate,
                                                         EventName.OnUpdateModel
                                                     }
                               },
                           {
                               EventGroup.PlayerModel, new[]
                                                           {
                                                               EventName.OnAnimFinished,
                                                               EventName.OnChar,
                                                               EventName.OnDragStart,
                                                               EventName.OnDragStop,
                                                               EventName.OnEnter,
                                                               EventName.OnEvent,
                                                               EventName.OnHide,
                                                               EventName.OnKeyDown,
                                                               EventName.OnKeyUp,
                                                               EventName.OnLeave,
                                                               EventName.OnLoad,
                                                               EventName.OnMouseDown,
                                                               EventName.OnMouseUp,
                                                               EventName.OnMouseWheel,
                                                               EventName.OnReceiveDrag,
                                                               EventName.OnShow,
                                                               EventName.OnSizeChanged,
                                                               EventName.OnUpdate,
                                                               EventName.OnUpdateModel
                                                           }
                               },
                           {
                               EventGroup.ScrollFrame, new[]
                                                           {
                                                               EventName.OnChar,
                                                               EventName.OnDragStart,
                                                               EventName.OnDragStop,
                                                               EventName.OnEnter,
                                                               EventName.OnEvent,
                                                               EventName.OnHide,
                                                               EventName.OnHorizontalScroll,
                                                               EventName.OnKeyDown,
                                                               EventName.OnKeyUp,
                                                               EventName.OnLeave,
                                                               EventName.OnLoad,
                                                               EventName.OnMouseDown,
                                                               EventName.OnMouseUp,
                                                               EventName.OnMouseWheel,
                                                               EventName.OnReceiveDrag,
                                                               EventName.OnScrollRangeChanged,
                                                               EventName.OnShow,
                                                               EventName.OnSizeChanged,
                                                               EventName.OnUpdate,
                                                               EventName.OnVerticalScroll
                                                           }
                               },
                           {
                               EventGroup.ScrollingMessageFrame, new[]
                                                                     {
                                                                         EventName.OnChar,
                                                                         EventName.OnDragStart,
                                                                         EventName.OnDragStop,
                                                                         EventName.OnEnter,
                                                                         EventName.OnEvent,
                                                                         EventName.OnHide,
                                                                         EventName.OnHyperlinkClick,
                                                                         EventName.OnHyperlinkEnter,
                                                                         EventName.OnHyperlinkLeave,
                                                                         EventName.OnKeyDown,
                                                                         EventName.OnKeyUp,
                                                                         EventName.OnLeave,
                                                                         EventName.OnLoad,
                                                                         EventName.OnMessageScrollChanged,
                                                                         EventName.OnMouseDown,
                                                                         EventName.OnMouseUp,
                                                                         EventName.OnMouseWheel,
                                                                         EventName.OnReceiveDrag,
                                                                         EventName.OnShow,
                                                                         EventName.OnSizeChanged,
                                                                         EventName.OnUpdate
                                                                     }
                               },
                           {
                               EventGroup.SimpleHTML, new[]
                                                          {
                                                              EventName.OnChar,
                                                              EventName.OnDragStart,
                                                              EventName.OnDragStop,
                                                              EventName.OnEnter,
                                                              EventName.OnEvent,
                                                              EventName.OnHide,
                                                              EventName.OnHyperlinkClick,
                                                              EventName.OnHyperlinkEnter,
                                                              EventName.OnHyperlinkLeave,
                                                              EventName.OnKeyDown,
                                                              EventName.OnKeyUp,
                                                              EventName.OnLeave,
                                                              EventName.OnLoad,
                                                              EventName.OnMouseDown,
                                                              EventName.OnMouseUp,
                                                              EventName.OnMouseWheel,
                                                              EventName.OnReceiveDrag,
                                                              EventName.OnShow,
                                                              EventName.OnSizeChanged,
                                                              EventName.OnUpdate
                                                          }
                               },
                           {
                               EventGroup.Slider, new[]
                                                      {
                                                          EventName.OnChar,
                                                          EventName.OnDragStart,
                                                          EventName.OnDragStop,
                                                          EventName.OnEnter,
                                                          EventName.OnEvent,
                                                          EventName.OnHide,
                                                          EventName.OnKeyDown,
                                                          EventName.OnKeyUp,
                                                          EventName.OnLeave,
                                                          EventName.OnLoad,
                                                          EventName.OnMouseDown,
                                                          EventName.OnMouseUp,
                                                          EventName.OnMouseWheel,
                                                          EventName.OnReceiveDrag,
                                                          EventName.OnShow,
                                                          EventName.OnSizeChanged,
                                                          EventName.OnUpdate,
                                                          EventName.OnValueChanged
                                                      }
                               },
                           {
                               EventGroup.StatusBar, new[]
                                                         {
                                                             EventName.OnChar,
                                                             EventName.OnDragStart,
                                                             EventName.OnDragStop,
                                                             EventName.OnEnter,
                                                             EventName.OnEvent,
                                                             EventName.OnHide,
                                                             EventName.OnKeyDown,
                                                             EventName.OnKeyUp,
                                                             EventName.OnLeave,
                                                             EventName.OnLoad,
                                                             EventName.OnMouseDown,
                                                             EventName.OnMouseUp,
                                                             EventName.OnMouseWheel,
                                                             EventName.OnReceiveDrag,
                                                             EventName.OnShow,
                                                             EventName.OnSizeChanged,
                                                             EventName.OnUpdate,
                                                             EventName.OnValueChanged
                                                         }
                               },
                           {
                               EventGroup.TabardModel, new[]
                                                           {
                                                               EventName.OnAnimFinished,
                                                               EventName.OnChar,
                                                               EventName.OnDragStart,
                                                               EventName.OnDragStop,
                                                               EventName.OnEnter,
                                                               EventName.OnEvent,
                                                               EventName.OnHide,
                                                               EventName.OnKeyDown,
                                                               EventName.OnKeyUp,
                                                               EventName.OnLeave,
                                                               EventName.OnLoad,
                                                               EventName.OnMouseDown,
                                                               EventName.OnMouseUp,
                                                               EventName.OnMouseWheel,
                                                               EventName.OnReceiveDrag,
                                                               EventName.OnShow,
                                                               EventName.OnSizeChanged,
                                                               EventName.OnUpdate,
                                                               EventName.OnUpdateModel
                                                           }
                               }
                       };
        }
        #endregion
        
        /// <summary>
        /// Gets the event names.
        /// </summary>
        /// <value>The event names.</value>
        public EventName[] GetEventNames()
        {
            return eventGroups.ContainsKey(EventGroup) ? eventGroups[EventGroup] : null;
        }
    }
}
